package com.zondy.mapgis.psmap.manager.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.zondy.mapgis.common.core.web.domain.AjaxResult;
import com.zondy.mapgis.domain.psmap.*;
import com.zondy.mapgis.domain.system.SysRole;
import com.zondy.mapgis.psmap.manager.constant.DataConstants;
import com.zondy.mapgis.psmap.manager.mapper.AppRoleDataMapper;
import com.zondy.mapgis.psmap.manager.mapper.AppRoleStoreWidgetMapper;
import com.zondy.mapgis.psmap.manager.service.IAppDataService;
import com.zondy.mapgis.psmap.manager.service.IAppPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AppPermissionServiceImpl implements IAppPermissionService {
   @Autowired
   private AppRoleStoreWidgetMapper appRoleStoreWidgetMapper;
   @Autowired
   private AppRoleDataMapper appRoleDataMapper;
   @Autowired
   private IAppDataService appDataService;

   @Override
   public List<AppStoreWidget> selectStoreWidgetByRoleId(Long roleId) {
      return this.appRoleStoreWidgetMapper.selectStoreWidgetByRoleId(roleId);
   }

   @Override
   public int updateWidgetPermission(AppPermission appPermission) {
      this.appRoleStoreWidgetMapper.deleteRoleStoreWidgetByRoleId(appPermission.getRoleId());
      return this.insertRoleStoreWidget(appPermission);
   }

   @Override
   public AjaxResult roleDataTreeSelect(Long roleId) {
      AppRoleData appRoleData = new AppRoleData();
      appRoleData.setRoleId(roleId);
      List<AppRoleData> appRoleDataList = this.appRoleDataMapper.selectAppRoleDataList(appRoleData);
      List<Long> dataIds = appRoleDataList.stream().map(AppRoleData::getDataId).collect(Collectors.toList());
      AjaxResult ajax = AjaxResult.success();
      List<AppData> appDataTree = this.appDataService.buildTreeDataForManager(null, DataConstants.ROOT_DATA_ID);
      ajax.put("dataTree", appDataTree);
      ajax.put("checkedKeys", this.filterCheckedKeys(appDataTree, dataIds));
      return ajax;
   }

   @Override
   @Transactional(
      rollbackFor = {Exception.class}
   )
   public int updateDataPermission(AppPermission appPermission) {
      int rows = 1;
      Long roleId = appPermission.getRoleId();
      Long[] dataIds = appPermission.getDataIds();
      List<AppRoleData> appRoleDataList = Arrays.stream(dataIds).map((dataId) -> {
         AppRoleData appRoleData = new AppRoleData();
         appRoleData.setRoleId(roleId);
         appRoleData.setDataId(dataId);
         return appRoleData;
      }).collect(Collectors.toList());
      this.appRoleDataMapper.deleteRoleDataByRoleId(roleId);
      if (!appRoleDataList.isEmpty()) {
         rows = this.appRoleDataMapper.batchRoleData(appRoleDataList);
      }

      return rows;
   }

   public int insertRoleStoreWidget(AppPermission appPermission) {
      int rows = 1;
      List<AppRoleStoreWidget> list = new ArrayList<>();
      String[] var4 = appPermission.getAppWidgetsIds();

       for (String appWidgetId : var4) {
           AppRoleStoreWidget rs = new AppRoleStoreWidget();
           rs.setRoleId(appPermission.getRoleId());
           rs.setAppWidgetId(appWidgetId);
           list.add(rs);
       }

      if (!list.isEmpty()) {
         list = list.stream().distinct().collect(Collectors.toList());
         rows = this.appRoleStoreWidgetMapper.batchRoleStoreWidget(list);
      }

      return rows;
   }

   private List<Long> filterCheckedKeys(List<AppData> appDataTree, List<Long> checkedKeys) {
      Map<Long, AppData> idToAppDataMap = new HashMap<>((int)Math.ceil((double)appDataTree.size() / 0.75) + 1);
      this.getAppDataTreeIds(appDataTree, idToAppDataMap);
      return checkedKeys.stream().filter(idToAppDataMap::containsKey).filter((key) -> {
         AppData appData = idToAppDataMap.get(key);
         int dataType = appData.getDataType();
         return dataType == 1 || dataType == 0 && appData.getChildren().isEmpty();
      }).collect(Collectors.toList());
   }

   private void getAppDataTreeIds(List<AppData> appDataTree, Map<Long, AppData> idToAppDataMap) {

       for (AppData appData : appDataTree) {
           idToAppDataMap.put(appData.getDataId(), appData);
           if (!appData.getChildren().isEmpty()) {
               this.getAppDataTreeIds(appData.getChildren(), idToAppDataMap);
           }
       }

   }

   private List<AppData> getAppDataListByRoleId(Long roleId) {
      List<AppData> appDataList;
      if (SysRole.isAdmin(roleId)) {
         AppData parentAppData = this.appDataService.selectAppDataByDataId(DataConstants.ROOT_DATA_ID);
         appDataList = this.appDataService.selectAppDataChildrenByDataId(DataConstants.ROOT_DATA_ID);
         return CollUtil.union(appDataList, Collections.singletonList(parentAppData)).stream().toList();
      } else {
         AppRoleData appRoleData = new AppRoleData();
         appRoleData.setRoleId(roleId);
         List<AppRoleData> appRoleDataList = this.appRoleDataMapper.selectAppRoleDataList(appRoleData);
         List<Long> dataIds = appRoleDataList.stream().map(AppRoleData::getDataId).toList();
         AppData appData = appDataService.selectAppDataByDataId(dataIds.get(0));
         return CollUtil.toList(appData);
      }
   }
}
